package com.mes.schedule.domain;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.annotations.GenericGenerator;
/**
 * 零件任务
 * date: Jun 22, 2015 3:46:06 PM <br/>  
 * @author Administrator  
 * @version   
 * @since JDK 1.6
 * @add Annotation cswen 2017/3/16
 */
@Entity
@org.hibernate.annotations.Entity(dynamicInsert=false,dynamicUpdate=false)
@Table(name = "T_SCHEDULE_PARTTASK")
public class SPartTask extends STask implements Serializable {
	
	public final static int TASKSTATE_DRAG = 101; // 草稿
	public final static int TASKSTATE_DISASSEMBLE = 102; // 已分解
	public final static int TASKSTATE_PLANED = 103; // 已计划
	public final static int TASKSTATE_ARRANGE = 104; // 已投产
	public final static int TASKSTATE_STARTED = 105; // 已开始
	public final static int TASKSTATE_COMPLETED = 106; // 已完成
	public final static int TASKSTATE_CANCELED = 107; // 已取消

	
	private static final long serialVersionUID = 1L;
	
	public SPartTask() {
		super();
		this.operationTaskList = new ArrayList<SOperationTask>();

	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return " 零件任务" + this.taskUid + "图号：" + this.drawingId + " 零件任务批次："
				+ this.batchNum;
	}

	public String toFriendlyString() {
		// TODO Auto-generated method stub
		return "任务:" + "图号：" + this.drawingId + " 批次：" + this.batchNum;
	}
	// add by hba
	/**
	 * 实际开始
	 */
	@Column(name = "EARLYSTART", length = 7)
	protected Date actualStart;
	/**
	 * 实际结束
	 */
	@Transient
	protected Date actualFinish;
	
	public Date getActualStart() {
		return actualStart;
	}

	public void setActualStart(Date actualStart) {
		this.actualStart = actualStart;
	}

	public Date getActualFinish() {
		return actualFinish;
	}

	public void setActualFinish(Date actualFinish) {
		this.actualFinish = actualFinish;
	}
	@Transient
	protected Date earlyStart;
	
	@Column(name = "LATEFINISH", length = 7)
	protected Date lateFinish;
	
	@Column(name = "PLANSTART", length = 7)
	protected Date planStart;
	
	@Column(name = "PLANFINISH", length = 7)
	protected Date planFinish;
	
	@Transient
	protected Date controlStart;
	
	@Column(name = "DEPTID")
	protected String deptUid;
	
	@Transient
	protected String deptName;
	@Transient
	protected String masterShopUid;
	@Transient
	protected String masterShopName;
	
	@Column(name = "PART_NUMBER")
	protected String partUid;
	
	@Column(name = "PART_NAME", length = 50)
	protected String partName;
	
	@Column(name = "DRAWINGID")
	protected String drawingId;
	
	@Column(name = "BATCHNUM")
	protected String batchNum;
	
	@Column(name = "MODEL")
	protected String model;
	
	@Transient
	protected Double demandLinkQty;
	@Transient
	protected double taskWork;
	@Transient
	protected double remainWork;
	@Transient
	protected int remainCriticalWork;
	@Transient
	protected SOperationTask nextTimeStone;
	/**
	 * 分批？
	 */
	@Transient
	protected boolean isSplitBatch;
	/**
	 * 分批工序唯一号
	 */
	@Transient
	protected String splitStartOperId;
	@Transient
	protected boolean isRootBatch;
	@Transient
	protected Integer delayDays;
	@Transient
	protected int delayReason;
	/**
	 * 分批工序唯一号
	 */
	@Transient
	protected  SOperationTask watchTask;
	@Transient
	protected double remainSlack;
	/**
	 * 分批工序任务List
	 */
	@Transient
	protected  List<SOperationTask> operationTaskList;
	/**
	 * 分批？
	 */
	@Transient
	protected  List<SPartTask> splitedBatchs;
	@Transient
	protected double waitTime;
	// 1--已进入调度
	// protected int taskScheduleType; // 0,普通零件任务，1--合批产生的任务，



	// public int getTaskScheduleType() {
	// return taskScheduleType;
	// }
	//
	// public void setTaskScheduleType(int taskScheduleType) {
	// this.taskScheduleType = taskScheduleType;
	// }
	
	/**
	 * 当前应用的工艺编号hba
	 */
	@Column(name="ROUTING")
	protected String Routing;
	/**
	 * @author lcs
	 * 零件任务的当前工序号
	 */
	@Transient
	protected String currentOperationIdString;
	
	public String getCurrentOperationIdString() {
		if (getCurrentOperation() != null) {
			currentOperationIdString = getCurrentOperation()
					.getOperationIdDesc();
		}
		return currentOperationIdString;
	}

	public void setCurrentOperationIdString(String currentOperationIdString) {
		this.currentOperationIdString = currentOperationIdString;
	}
	public String getRouting() {
		return Routing;
	}

	public void setRouting(String routing) {
		Routing = routing;
	}

	/**
	 * @return the masterShopName
	 */
	public String getMasterShopName() {
		return masterShopName;
	}

	/**
	 * @param masterShopName
	 *            the masterShopName to set
	 */
	public void setMasterShopName(String masterShopName) {
		this.masterShopName = masterShopName;
	}

	/**
	 * @return the earlyStart
	 */
	public Date getEarlyStart() {
		return earlyStart;
	}

	/**
	 * @param earlyStart
	 *            the earlyStart to set
	 */
	public void setEarlyStart(Date earlyStart) {
		this.earlyStart = earlyStart;
	}

	/**
	 * @return the lateFinish
	 */
	public Date getLateFinish() {
		return lateFinish;
	}

	/**
	 * @param lateFinish
	 *            the lateFinish to set
	 */
	public void setLateFinish(Date lateFinish) {
		this.lateFinish = lateFinish;
	}

	/**
	 * @return the planStart
	 */
	public Date getPlanStart() {
		return planStart;
	}

	/**
	 * @param planStart
	 *            the planStart to set
	 */
	public void setPlanStart(Date planStart) {
		this.planStart = planStart;
	}

	/**
	 * @return the planFinish
	 */
	public Date getPlanFinish() {
		return planFinish;
	}

	/**
	 * @param planFinish
	 *            the planFinish to set
	 */
	public void setPlanFinish(Date planFinish) {
		this.planFinish = planFinish;
	}

	/**
	 * @return the controlStart
	 */
	public Date getControlStart() {
		return controlStart;
	}

	/**
	 * @param controlStart
	 *            the controlStart to set
	 */
	public void setControlStart(Date controlStart) {
		this.controlStart = controlStart;
	}

	/**
	 * @return the deptUid
	 */
	public String getDeptUid() {
		return deptUid;
	}

	/**
	 * @param deptUid
	 *            the deptUid to set
	 */
	public void setDeptUid(String deptUid) {
		this.deptUid = deptUid;
	}

	/**
	 * @return the masterShopUid
	 */
	public String getMasterShopUid() {
		return masterShopUid;
	}

	/**
	 * @param masterShopUid
	 *            the masterShopUid to set
	 */
	public void setMasterShopUid(String masterShopUid) {
		this.masterShopUid = masterShopUid;
	}

	/**
	 * @return the remainWork
	 */
	public double getRemainWork() {
		return remainWork;
	}

	/**
	 * @param remainWork
	 *            the remainWork to set
	 */
	public void setRemainWork(double remainWork) {
		this.remainWork = remainWork;
	}

	/**
	 * @return the partUid
	 */
	public String getPartUid() {
		return partUid;
	}

	/**
	 * @param partUid
	 *            the partUid to set
	 */
	public void setPartUid(String partUid) {
		this.partUid = partUid;
	}

	/**
	 * @return the batchNum
	 */
	public String getBatchNum() {
		return batchNum;
	}

	/**
	 * @param batchNum
	 *            the batchNum to set
	 */
	public void setBatchNum(String batchNum) {
		this.batchNum = batchNum;
	}

	/**
	 * @return the drawingId
	 */
	public String getDrawingId() {
		return drawingId;
	}

	/**
	 * @param drawingId
	 *            the drawingId to set
	 */
	public void setDrawingId(String drawingId) {
		this.drawingId = drawingId;
	}

	/**
	 * @return the partName
	 */
	public String getPartName() {
		return partName;
	}

	/**
	 * @param partName
	 *            the partName to set
	 */
	public void setPartName(String partName) {
		this.partName = partName;
	}

	/**
	 * @return the model
	 */
	public String getModel() {
		return model;
	}

	/**
	 * @param model
	 *            the model to set
	 */
	public void setModel(String model) {
		this.model = model;
	}

	/**
	 * @return the nextTimeStone
	 */
	public SOperationTask getNextTimeStone() {
		return nextTimeStone;
	}

	/**
	 * @param nextTimeStone
	 *            the nextTimeStone to set
	 */
	public void setNextTimeStone(SOperationTask nextTimeStone) {
		this.nextTimeStone = nextTimeStone;
	}

	/**
	 * @return the isSplitBatch
	 */
	public boolean isSplitBatch() {
		return isSplitBatch;
	}

	/**
	 * @param isSplitBatch
	 *            the isSplitBatch to set
	 */
	public void setSplitBatch(boolean isSplitBatch) {
		this.isSplitBatch = isSplitBatch;
	}

	/**
	 * @return the splitStartOperId
	 */
	public String getSplitStartOperId() {
		return splitStartOperId;
	}

	/**
	 * @param splitStartOperId
	 *            the splitStartOperId to set
	 */
	public void setSplitStartOperId(String splitStartOperId) {
		this.splitStartOperId = splitStartOperId;
	}

	/**
	 * @return the isRootBatch
	 */
	public boolean isRootBatch() {
		return isRootBatch;
	}

	/**
	 * @param isRootBatch
	 *            the isRootBatch to set
	 */
	public void setRootBatch(boolean isRootBatch) {
		this.isRootBatch = isRootBatch;
	}



	/**
	 * @return the deptName
	 */
	public String getDeptName() {
		return deptName;
	}

	/**
	 * @param deptName
	 *            the deptName to set
	 */
	public void setDeptName(String deptName) {
		this.deptName = deptName;
	}

	// /**
	// * @return the taskState
	// */
	// public int getTaskState() {
	// return taskState;
	// }
	//
	// /**
	// * @param taskState
	// * the taskState to set
	// */
	// public void setTaskState(int taskState) {
	// this.taskState = taskState;
	// }

	/**
	 * @return the remainCriticalWork
	 */
	public int getRemainCriticalWork() {
		return remainCriticalWork;
	}

	/**
	 * @param remainCriticalWork
	 *            the remainCriticalWork to set
	 */
	public void setRemainCriticalWork(int remainCriticalWork) {
		this.remainCriticalWork = remainCriticalWork;
	}

	/**
	 * @param remainWork
	 *            the remainWork to set
	 */
	public void setRemainWork(long remainWork) {
		this.remainWork = remainWork;
	}

	/**
	 * @return the currentOperation
	 */
	public SOperationTask getCurrentOperation() {
		SOperationTask currentOperation = null;

		if (this.operationTaskList != null && this.operationTaskList.size() > 0) {
			SOperationTask f = operationTaskList.get(0);
			if (f != null)
				currentOperation = f;
		}

		return currentOperation;
	}

	/**
	 * @return the taskWork
	 */
	public double getTaskWork() {
		return taskWork;
	}

	/**
	 * @param taskWork
	 *            the taskWork to set
	 */
	public void setTaskWork(double taskWork) {
		this.taskWork = taskWork;
	}

	/**
	 * @return the delayDays
	 */
	public Integer getDelayDays() {
		if (this.lateFinish != null && this.planFinish != null) {
			int delayDays = (int) Math
					.round((this.planFinish.getTime() - this.lateFinish
							.getTime())
							/ (60000 * 1440));
			return delayDays;
			// partTask.setDelayDays(delayDays);
		}

		return null;
	}

	/**
	 * @param delayDays
	 *            the delayDays to set
	 */
	public void setDelayDays(Integer delayDays) {
		this.delayDays = delayDays;
	}

	/**
	 * @return the delayReason
	 */
	public int getDelayReason() {
		return delayReason;
	}

	/**
	 * @param delayReason
	 *            the delayReason to set
	 */
	public void setDelayReason(int delayReason) {
		this.delayReason = delayReason;
	}

	/**
	 * @return the remainSlack
	 */
	public double getRemainSlack() {
		return remainSlack;
	}

	/**
	 * @param remainSlack
	 *            the remainSlack to set
	 */
	public void setRemainSlack(double remainSlack) {
		this.remainSlack = remainSlack;
	}

	/**
	 * @return the watchTask
	 */
	public SOperationTask getWatchTask() {
		return watchTask;
	}

	/**
	 * @param watchTask
	 *            the watchTask to set
	 */
	public void setWatchTask(SOperationTask watchTask) {
		this.watchTask = watchTask;
	}

	public static Object copy(Object oldObj) {
		Object obj = null;
		try {
			// Write the object out to a byte array

			ByteArrayOutputStream bos = new ByteArrayOutputStream();

			ObjectOutputStream out = new ObjectOutputStream(bos);

			out.writeObject(oldObj);
			out.flush();
			out.close();
			// Retrieve an input stream from the byte array and read

			// a copy of the object back in.

			ByteArrayInputStream bis = new ByteArrayInputStream(bos
					.toByteArray());
			ObjectInputStream in = new ObjectInputStream(bis);
			obj = in.readObject();

		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException cnfe) {
			cnfe.printStackTrace();
		}
		return obj;
	}

	/**
	 * 工序任务集合
	 * @return the operationTaskList
	 */
	public List<SOperationTask> getOperationTaskList() {
		return operationTaskList;
	}

	/**
	 * @param operationTaskList
	 *            the operationTaskList to set
	 */
	public void setOperationTaskList(List<SOperationTask> operationTaskList) {
		this.operationTaskList = operationTaskList;
	}

	/**
	 * @return the splitedBatchs
	 */
	public List<SPartTask> getSplitedBatchs() {
		return splitedBatchs;
	}

	/**
	 * @param splitedBatchs
	 *            the splitedBatchs to set
	 */
	public void setSplitedBatchs(List<SPartTask> splitedBatchs) {
		this.splitedBatchs = splitedBatchs;
	}
	


	
	

	/**
	 * @return the combinedBatchs
	 */
	public List<SPartTask> getCombinedBatchs() {
		List<SPartTask> combinedBatchs = new ArrayList<SPartTask>();
		try {
			if (this.getTaskScheduleType() == SPartTask.TASKSCHEDULETYPE_COMBINEBATCH
					&& this.batchNum != null && this.batchNum.length() > 0)//
			{

				String[] strBatchNums = this.batchNum.split(",");
				/**
				 * 在由dorado 向其中传递数据时scheme为空，现在是在sheduleSchemeManager中强行注入了一个scheme
				 * 以后还是应该讲combinedBatchs实体化
				 */
				for (SPartTask sp : this.scheme.allPartTaskMap.values()) {
					for (int i = 0; i < strBatchNums.length; i++) {

						if (sp.partUid != null
								&& sp.batchNum != null
								&& this.partUid != null
								&& sp.partUid.equals(this.partUid)
								&& sp.getBatchNum().equals(strBatchNums[i])
								&& (sp.taskScheduleType!=null&&sp.taskScheduleType == SPartTask.TASKSCHEDULETYPE_NORMAL)) {
							combinedBatchs.add(sp);
							break;
						}
					}
				}
				if (combinedBatchs.size() > 1) {
					Collections.sort(combinedBatchs, new Comparator<Object>() {

						public int compare(Object o1, Object o2) {
							SPartTask partTask1 = (SPartTask) o1;
							SPartTask partTask2 = (SPartTask) o2;
							int i = 0;
							if (partTask1.getBatchNum().compareTo(
									partTask2.getBatchNum()) > 0) {
								i = 1;
							}
							return i;
						}

					});
				}
			}
		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return combinedBatchs;
	}



	public SOperationTask getByIddesc(String OperationIDDesc) {
		SOperationTask so = null;
		for (SOperationTask o : this.operationTaskList) {
			if (o.getOperationIdDesc().equalsIgnoreCase(OperationIDDesc))
				so = o;

		}
		return so;
	}

	public void sortByOperationId() {
		if (operationTaskList == null || operationTaskList.isEmpty()) {
			return;
		} else {
			Collections.sort(operationTaskList, new Comparator<Object>() {
				public int compare(Object o1, Object o2) {
					SOperationTask operTask1 = (SOperationTask) o1;
					SOperationTask operTask2 = (SOperationTask) o2;
					if(operTask1.equals(operTask2))
						return 0;
					
					
					//千万不要出现那种=0的现象，否则会出现一些工序无法看见的现象
					//lqm todo
					if (operTask1.getOperationId() > operTask2.getOperationId())
						return 1;
					else
						return -1;

				} 
			});

		}

	}





	public Double getDemandLinkQty() {
		return demandLinkQty;
	}

	public void setDemandLinkQty(Double demandLinkQty) {
		this.demandLinkQty = demandLinkQty;
	}

	public double getWaitTime() {
		return waitTime;
	}

	public void setWaitTime(double waitTime) {
		this.waitTime = waitTime;
	}
	
	@Override
	public void destroy() {
		try {
			// TODO Auto-generated method stub
			super.destroy();
			if(this.operationTaskList!=null)
			{
			this.operationTaskList.clear();
			this.operationTaskList=null;
			}
		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	@Id
	@GenericGenerator(name="uuid", strategy="assigned")
	@Column(name="UUID")
	private String uuid;

	public String getUuid() {
		return uuid;
	}

	public void setUuid(String uuid) {
		this.uuid = uuid;
	}

	//author by lcs
	@Column(name="PLANGRADE")
	private double plangrade;

	public double getPlangrade() {
		return plangrade;
	}

	public void setPlangrade(double plangrade) {
		this.plangrade = plangrade;
	}
	
	
}
